package com.yang.thread;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程池示例 - 演示ExecutorService的使用
 * 线程池可以重用线程，避免频繁创建和销毁线程的开销
 */
public class ThreadPoolExample {
    
    public static void main(String[] args) {
        System.out.println("=== 线程池示例 ===");
        
        // 1. 固定大小线程池
        demonstrateFixedThreadPool();
        
        // 2. 缓存线程池
        demonstrateCachedThreadPool();
        
        // 3. 单线程池
        demonstrateSingleThreadPool();
        
        // 4. 定时任务线程池
        demonstrateScheduledThreadPool();
        
        // 5. 自定义线程池
        demonstrateCustomThreadPool();
    }
    
    /**
     * 固定大小线程池演示
     */
    private static void demonstrateFixedThreadPool() {
        System.out.println("\n--- 固定大小线程池 (3个线程) ---");
        
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 提交10个任务
        for (int i = 1; i <= 10; i++) {
            final int taskId = i;
            executor.submit(new ComputeTask(taskId));
        }
        
        // 关闭线程池
        executor.shutdown();
        try {
            if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 缓存线程池演示
     */
    private static void demonstrateCachedThreadPool() {
        System.out.println("\n--- 缓存线程池 (根据需要创建线程) ---");
        
        ExecutorService executor = Executors.newCachedThreadPool();
        
        // 提交5个任务
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("缓存线程池任务 " + taskId + 
                                 " 执行中 [线程: " + Thread.currentThread().getName() + "]");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("缓存线程池任务 " + taskId + " 完成");
            });
        }
        
        executor.shutdown();
        try {
            executor.awaitTermination(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 单线程池演示
     */
    private static void demonstrateSingleThreadPool() {
        System.out.println("\n--- 单线程池 (保证任务顺序执行) ---");
        
        ExecutorService executor = Executors.newSingleThreadExecutor();
        
        // 提交5个任务，它们会按顺序执行
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("单线程任务 " + taskId + " 开始执行");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("单线程任务 " + taskId + " 执行完成");
            });
        }
        
        executor.shutdown();
        try {
            executor.awaitTermination(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 定时任务线程池演示
     */
    private static void demonstrateScheduledThreadPool() {
        System.out.println("\n--- 定时任务线程池 ---");
        
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
        
        // 延迟执行任务
        scheduler.schedule(() -> {
            System.out.println("延迟2秒执行的任务");
        }, 2, TimeUnit.SECONDS);
        
        // 周期性执行任务
        AtomicInteger counter = new AtomicInteger(0);
        ScheduledFuture<?> periodicTask = scheduler.scheduleAtFixedRate(() -> {
            int count = counter.incrementAndGet();
            System.out.println("周期性任务执行第 " + count + " 次");
            if (count >= 3) {
                System.out.println("周期性任务执行完毕");
            }
        }, 1, 1, TimeUnit.SECONDS);
        
        // 3秒后取消周期性任务
        scheduler.schedule(() -> {
            periodicTask.cancel(false);
            scheduler.shutdown();
        }, 4, TimeUnit.SECONDS);
        
        try {
            scheduler.awaitTermination(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 自定义线程池演示
     */
    private static void demonstrateCustomThreadPool() {
        System.out.println("\n--- 自定义线程池 ---");
        
        // 创建自定义线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2,                      // 核心线程数
            4,                      // 最大线程数
            60L,                    // 空闲线程存活时间
            TimeUnit.SECONDS,       // 时间单位
            new LinkedBlockingQueue<>(10), // 工作队列
            new ThreadFactory() {   // 线程工厂
                private AtomicInteger threadNumber = new AtomicInteger(1);
                
                @Override
                public Thread newThread(Runnable r) {
                    Thread t = new Thread(r, "自定义线程-" + threadNumber.getAndIncrement());
                    t.setDaemon(false);
                    return t;
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
        );
        
        // 提交任务
        for (int i = 1; i <= 8; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("自定义线程池任务 " + taskId + 
                                 " [线程: " + Thread.currentThread().getName() + 
                                 ", 活跃线程数: " + executor.getActiveCount() + "]");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("自定义线程池任务 " + taskId + " 完成");
            });
        }
        
        // 监控线程池状态
        new Thread(() -> {
            while (!executor.isTerminated()) {
                System.out.println("线程池状态 - 核心线程数: " + executor.getCorePoolSize() + 
                                 ", 当前线程数: " + executor.getPoolSize() + 
                                 ", 活跃线程数: " + executor.getActiveCount() + 
                                 ", 队列大小: " + executor.getQueue().size());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }).start();
        
        executor.shutdown();
        try {
            executor.awaitTermination(20, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

/**
 * 计算任务类
 */
class ComputeTask implements Runnable {
    private final int taskId;
    
    public ComputeTask(int taskId) {
        this.taskId = taskId;
    }
    
    @Override
    public void run() {
        System.out.println("任务 " + taskId + " 开始执行 [线程: " + 
                          Thread.currentThread().getName() + "]");
        
        // 模拟计算工作
        long sum = 0;
        for (int i = 0; i < 1000000; i++) {
            sum += i;
        }
        
        try {
            Thread.sleep(2000); // 模拟耗时操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.out.println("任务 " + taskId + " 被中断");
            return;
        }
        
        System.out.println("任务 " + taskId + " 执行完成，计算结果: " + sum);
    }
}
